package com.xiaozhen.system.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xiaozhen.common.core.constant.UserConstants;
import com.xiaozhen.security.controller.BaseController;
import com.xiaozhen.common.core.domain.AjaxResult;
import com.xiaozhen.common.core.domain.R;
import com.xiaozhen.common.core.domain.system.SysRole;
import com.xiaozhen.common.core.domain.system.vo.SysUserListVo;
import com.xiaozhen.common.core.domain.system.queryParams.SysUserQueryParam;
import com.xiaozhen.common.core.utils.SecurityUtils;
import com.xiaozhen.common.core.utils.StringUtils;
import com.xiaozhen.common.core.utils.UserUtils;
import com.xiaozhen.common.core.domain.system.SysUser;
import com.xiaozhen.system.service.SysMenuService;
import com.xiaozhen.system.service.SysRoleService;
import com.xiaozhen.system.service.SysUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * HISTORY
 *
 * @author zhenweisheng
 * @date 2021/8/5 10:22
 * @description:
 */
@RestController
@Api(tags = "系统用户接口")
@RequestMapping("/sysUser")
public class SysUserController extends BaseController {

    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SysRoleService sysRoleService;
    @Autowired
    private SysMenuService sysMenuService;

    /**
     * 根据用户名查询用户信息
     *
     * @param username
     * @return
     */
    @ApiOperation("根据用户名查询用户信息(OAUTH2.0)")
    @PostMapping("/selectByUsername")
    @ApiImplicitParam(name = "username", value = "用户名", required = true)
    @ApiResponse(code = 200, message = "请求成功", response = SysUser.class)
    public R<SysUser> selectByUsername(@RequestParam("username") String username) {
        SysUser sysUser = sysUserService.selectByUsername(username);
        //查询用户的权限集合
        Set<String> permissions = sysMenuService.getMenuPermission(sysUser);
        sysUser.setPermissions(new ArrayList<>(permissions));
        return R.ok(sysUser);
    }


    /**
     * 获取用户信息
     */
    @ApiOperation("获取用户信息(登录之后拉取)")
    @GetMapping("/getInfo")
    public AjaxResult getInfo() {
        //根据用户ID从缓存中获取用户信息
        SysUser sysUser = sysUserService.selectUserById(getCurrentUserId());
        //查询用户的角色集合
        Set<String> roles = sysRoleService.getRolePermission(sysUser);
        //查询用户的权限集合
        Set<String> permissions = sysMenuService.getMenuPermission(sysUser);
        AjaxResult ajax = AjaxResult.success();
        ajax.put("user", sysUser);
        ajax.put("roles", roles);
        ajax.put("permissions", permissions);
        return ajax;
    }

    /**
     * 获取用户列表
     */
    @ApiOperation("获取用户列表")
    @GetMapping("/list")
    public AjaxResult list(SysUserQueryParam queryParam) {
        Page<SysUser> page = startPage();
        Page<SysUserListVo> list = sysUserService.selectUserList(page, queryParam);
        return getDataTable(list);
    }

    /**
     * 修改用户状态
     *
     * @param sysUser
     * @return
     */
    @ApiOperation("修改用户状态")
    @PutMapping("changeUserStatus")
    public AjaxResult changeStatus(@RequestBody SysUser sysUser) {
        sysUserService.checkUserAllowed(sysUser);
        sysUser.setUpdateBy(getCurrentUserId());
        return toAjax(sysUserService.updateUserStatus(sysUser));
    }

    /**
     * 根据用户ID获取用户详细信息
     */
    @ApiOperation("根据用户ID获取用户详细信息")
    @GetMapping(value = {"/", "/{userId}"})
    public AjaxResult getInfo(@PathVariable(value = "userId", required = false) Long userId) {
        AjaxResult ajax = AjaxResult.success();
        List<SysRole> roles = sysRoleService.selectRoleAll();
        //如果是管理员返回全部  不然去除管理员权限
        ajax.put("roles", UserUtils.isAdmin(userId) ? roles :
                roles.stream().filter(r -> !UserUtils.isAdminRole(r)).collect(Collectors.toList()));
        if (StringUtils.isNotNull(userId)) {
            ajax.put(AjaxResult.DATA_TAG, sysUserService.selectUserById(userId));
            ajax.put("roleIds", sysRoleService.selectRoleListByUserId(userId));
        }
        return ajax;
    }

    @ApiOperation("新增用户")
    @PostMapping("/add")
    public AjaxResult add(@Validated @RequestBody SysUser user) {
        if (!sysUserService.checkUserNameUnique(user.getUserName())) {
            return AjaxResult.error("新增用户'" + user.getUserName() + "'失败，登录账号已存在");
        }
        if (StringUtils.isNotEmpty(user.getPhonenumber())
                && !sysUserService.checkPhoneUnique(user)) {
            return AjaxResult.error("新增用户'" + user.getUserName() + "'失败，手机号码已存在");
        }
        if (StringUtils.isNotEmpty(user.getEmail())
                && !sysUserService.checkEmailUnique(user)) {
            return AjaxResult.error("新增用户'" + user.getUserName() + "'失败，邮箱账号已存在");
        }
        user.setCreateBy(getCurrentUserId());
        user.setCreateTime(LocalDateTime.now());
        user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
        return toAjax(sysUserService.insertUser(user));
    }

    @ApiOperation("修改用户")
    @PutMapping("/update")
    public AjaxResult edit(@Validated @RequestBody SysUser user) {
        sysUserService.checkUserAllowed(user);
        if (StringUtils.isNotEmpty(user.getPhonenumber())
                && !sysUserService.checkPhoneUnique(user)) {
            return AjaxResult.error("修改用户'" + user.getUserName() + "'失败，手机号码已存在");
        }
        if (StringUtils.isNotEmpty(user.getEmail())
                && !sysUserService.checkEmailUnique(user)) {
            return AjaxResult.error("修改用户'" + user.getUserName() + "'失败，邮箱账号已存在");
        }
        user.setUpdateBy(getCurrentUserId());
        user.setUpdateTime(LocalDateTime.now());
        return toAjax(sysUserService.updateUser(user));
    }

    @ApiOperation("删除用户")
    @DeleteMapping("/{userIds}")
    public AjaxResult remove(@PathVariable Long[] userIds) {
        if (ArrayUtils.contains(userIds, getCurrentUserId())) {
            return AjaxResult.error("当前用户不能删除");
        }
        return toAjax(sysUserService.deleteUserByIds(userIds));
    }
}
